home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 105 (1991-02)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 105 (1991-02)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / AmigaUUCP / uucico / sysdep.c < prev    next >
C/C++ Source or Header  |  1991-02-14  |  13KB  |  689 lines

  1.  
  2. /*
  3.  *  SYSDEP.C
  4.  *
  5.  *  $Header: Beta:src/uucp/src/uucico/RCS/sysdep.c,v 1.1 90/02/02 11:56:16 dillon Exp Locker: dillon $
  6.  *
  7.  * (C) Copyright 1987 by John Gilmore
  8.  * Copying and use of this program are controlled by the terms of the Free
  9.  * Software Foundation's GNU Emacs General Public License.
  10.  *
  11.  *  Amiga Changes Copyright 1988 by William Loftus. All rights reserved.
  12.  *  Additional chgs Copyright 1989 by Matthew Dillon, All Rights Reserved.
  13.  */
  14.  
  15. #include <exec/types.h>
  16. #include <exec/exec.h>
  17. #include "includes.h"
  18. #include <hardware/cia.h>
  19. #include <devices/timer.h>
  20. #include <devices/serial.h>
  21. #include <libraries/dos.h>
  22. #include <pwd.h>
  23. #include "uucp.h"
  24. #include "version.h"
  25.  
  26. #define Assert(x)   if (!(x)) _assert_failed(__LINE__);
  27.  
  28. Prototype int openout(char *, int);
  29. Prototype int sigint(void);
  30. Prototype void cleanup(void);
  31. Prototype int xdatardy(void);
  32. Prototype int xgetc(int);
  33. Prototype int xwrite(const void *, int);
  34. Prototype int xwritea(const void *, int);
  35. Prototype int xxwrite(const void *, int, int);
  36. Prototype void SendBreak(void);
  37. Prototype int CheckCarrier(void);
  38. Prototype void *bzero(void *, long);
  39. Prototype void *bcopy(const void *, void *, long);
  40. Prototype void munge_filename(char *, char *);
  41. Prototype int hangup(void);
  42. Prototype int work_scan(char *);
  43. Prototype char *work_next(void);
  44. Prototype void amiga_setup(void);
  45. Prototype void set_baud(int);
  46. Prototype void OpenSerial(int);
  47. Prototype void CloseSerial(int);
  48. Prototype void xexit(int);
  49. Prototype void printc(unsigned char);
  50.  
  51. static void _assert_failed(int);
  52.  
  53. IDENT(".03");
  54.  
  55. /*
  56.  *  Split out of uuslave.c by John Gilmore, 8 August 1987.
  57.  *  ported to the Amiga by William Loftus, 20 September 1987.
  58.  *  rewritten by Matthew Dillon, October 1989
  59.  */
  60.  
  61. /* FIXME -- System dependent defines (not really -- should be in a .h) */
  62. /*
  63.  * Timeout for raw characters -- if we don't hear a char within BYTE_TIMEOUT
  64.  * seconds, we assume the other side has gone away.  Has nothing to do with
  65.  * retransmission timeouts (if any!).
  66.  */
  67.  
  68. extern int debug;
  69. extern int SevenWire;
  70.  
  71. #define FAILURE  1
  72.  
  73. struct IOExtSer Iosr;
  74. struct IOExtSer Iosw;
  75. struct IOExtSer Ioss;
  76. struct timerequest Iot0;
  77. char   *OldTaskName;
  78.  
  79. char    *DeviceName = "serial.device";
  80. long    DeviceUnit = 0;
  81.  
  82. unsigned char    XInBuf[256];       /*  for xgetc() */
  83. char    LockFileName[128];
  84. short    XInIdx = 0;
  85. short    XInLen = 0;
  86. short    IoswIP = 0;
  87. short    IosrIP = 0;
  88. short    IotIP = 0;
  89.  
  90. short    InExitRoutine = 0;
  91. short    debugRead = 0;
  92.  
  93. extern char path[];
  94. extern int Getty;
  95. extern int IgnoreCD;
  96.  
  97. int
  98. openout(acu, baud)
  99. char *acu;
  100. int  baud;
  101. {
  102.     set_baud(baud);
  103.  
  104.     return SUCCESS;
  105. }
  106.  
  107. /*
  108.  * Basement level I/O routines
  109.  *
  110.  * xwrite() writes a character string to the serial port
  111.  * xgetc() returns a character from the serial port, or an EOF for timeout.
  112.  * sigint() restores the state of the serial port on exit.
  113.  */
  114.  
  115. int
  116. sigint()
  117. {
  118.     xexit(2);
  119.     return(0);
  120. }
  121.  
  122.  
  123. void
  124. cleanup()
  125. {
  126.     xexit(0);
  127. }
  128.  
  129. int
  130. xdatardy()
  131. {
  132.     if (XInIdx != XInLen)
  133.     return(1);
  134.     CheckCarrier();
  135.     return (Ioss.IOSer.io_Actual > 0);
  136. }
  137.  
  138. int
  139. xgetc(byteto)
  140. int byteto;
  141. {
  142.     int ch, n;
  143.     long smask;
  144.     long tmask;
  145.     short bytetimeout;
  146.  
  147. top:
  148.     if (XInIdx != XInLen) {
  149.     if (debug > 8) {
  150.         if (debugRead == 0)
  151.         printf("\nREAD: ");
  152.         debugRead = 1;
  153.         printc(XInBuf[XInIdx]);
  154.     }
  155.     return((int)XInBuf[XInIdx++]);
  156.     }
  157.  
  158.     XInIdx = 0;
  159.     XInLen = 0;
  160.  
  161.     if (!CheckCarrier())                        /*  carrier lost?     */
  162.     return(EOF);
  163.  
  164.     Assert(Iosr.IOSer.io_Device);
  165.  
  166.     if ((n = Ioss.IOSer.io_Actual) > 0) {       /*  at least one..    */
  167.     Iosr.IOSer.io_Command = CMD_READ;
  168.     Iosr.IOSer.io_Data = (APTR)XInBuf;
  169.     if (n > sizeof(XInBuf))
  170.         n = sizeof(XInBuf);
  171.     Iosr.IOSer.io_Length = n;
  172.     DoIO(&Iosr);
  173.     if (Iosr.IOSer.io_Actual > 0) {
  174.         if (debug > 8)
  175.         printf("(r%d/%d)", n, Iosr.IOSer.io_Actual);
  176.         XInIdx = 0;
  177.         XInLen = Iosr.IOSer.io_Actual;
  178.         goto top;
  179.     }
  180.     }
  181.  
  182.     /*
  183.      *    no bytes ready, byteto is 0 (no wait)
  184.      */
  185.  
  186.     if (byteto == 0)
  187.     return(EOF);
  188.  
  189.     /*
  190.      *    no bytes ready, wait for one.
  191.      *
  192.      *    once every 3 seconds check carrier detect.
  193.      */
  194.  
  195.     bytetimeout = byteto;
  196.     Iot0.tr_time.tv_secs = 3;
  197.     Iot0.tr_time.tv_micro= 0;
  198.     SendIO(&Iot0);
  199.     IotIP = 1;
  200.  
  201.     Iosr.IOSer.io_Command = CMD_READ;
  202.     Iosr.IOSer.io_Data = (APTR)XInBuf;
  203.     Iosr.IOSer.io_Length = 1;
  204.     Iosr.IOSer.io_Actual = 0;    /*  trying to find a bug... */
  205.     SendIO(&Iosr);
  206.     IosrIP = 1;
  207.  
  208.     smask = 1L << Iosr.IOSer.io_Message.mn_ReplyPort->mp_SigBit;
  209.     tmask = 1L << Iot0.tr_node.io_Message.mn_ReplyPort->mp_SigBit;
  210.  
  211.     for (;;) {
  212.     long mask = Wait(tmask | smask | SIGBREAKF_CTRL_C);
  213.  
  214.     if (mask & SIGBREAKF_CTRL_C) {
  215.         AbortIO(&Iosr);
  216.         WaitIO(&Iosr);
  217.         IosrIP = 0;
  218.         AbortIO(&Iot0);
  219.         WaitIO(&Iot0);
  220.         IotIP = 0;
  221.         xexit(3);
  222.     }
  223.     if (CheckIO(&Iosr)) {
  224.         WaitIO(&Iosr);
  225.         IosrIP = 0;
  226.         AbortIO(&Iot0);
  227.         WaitIO(&Iot0);
  228.         IotIP = 0;
  229.  
  230.         ch = (int)XInBuf[0];
  231.  
  232.         if (debug > 8) {
  233.         if (debugRead == 0)
  234.             printf("\nREAD ");
  235.         debugRead = 1;
  236.         printf("(waitc%d)", Iosr.IOSer.io_Actual);
  237.         printc((unsigned char)ch);
  238.         }
  239.         return(ch);
  240.     }
  241.     if (CheckIO(&Iot0)) {
  242.         WaitIO(&Iot0);
  243.         IotIP = 0;
  244.  
  245.         Iot0.tr_time.tv_secs = 3;
  246.         Iot0.tr_time.tv_micro= 0;
  247.  
  248.         bytetimeout -= Iot0.tr_time.tv_secs;
  249.         if (bytetimeout > 0) {
  250.         if (CheckCarrier() == 0) {
  251.             AbortIO(&Iosr);
  252.             WaitIO(&Iosr);
  253.             IosrIP = 0;
  254.             break;
  255.         }
  256.         SendIO(&Iot0);
  257.         IotIP = 1;
  258.         } else {
  259.         AbortIO(&Iosr);
  260.         WaitIO(&Iosr);
  261.         IosrIP = 0;
  262.         if (Iosr.IOSer.io_Actual == 1)
  263.             return((int)XInBuf[0]);
  264.         break;
  265.         }
  266.     }
  267.     }
  268.     if (debug > 8)
  269.     printf("\nRecv-EOF\n");
  270.     return(EOF);
  271. }
  272.  
  273. int
  274. xwrite(buf, ctr)
  275. const void *buf;
  276. int ctr;
  277. {
  278.     return(xxwrite(buf, ctr, 0));
  279. }
  280.  
  281. int
  282. xwritea(buf, ctr)
  283. const void *buf;
  284. int ctr;
  285. {
  286.     xxwrite(buf, ctr, 1);
  287.     return(ctr);
  288. }
  289.  
  290. int
  291. xxwrite(buf, ctr, async)
  292. const void *buf;
  293. int ctr;
  294. int async;
  295. {
  296.     Assert(Iosr.IOSer.io_Device);
  297.     if (debug > 8) {
  298.     short i;
  299.     if (debugRead)
  300.         printf("\nWRITE ");
  301.     debugRead = 0;
  302.     for (i = 0; i < ctr; ++i) {
  303.         printc(((unsigned char *)buf)[i]);
  304.     }
  305.     printf("\n");
  306.     }
  307.     if (IoswIP) {
  308.     WaitIO(&Iosw);
  309.     IoswIP = 0;
  310.     }
  311.  
  312.     Iosw.IOSer.io_Command = CMD_WRITE;
  313.     Iosw.IOSer.io_Length = ctr;
  314.     Iosw.IOSer.io_Data = (APTR)buf;
  315.     if (async) {
  316.     SendIO(&Iosw);
  317.     IoswIP = 1;
  318.     } else {
  319.     DoIO(&Iosw);
  320.     }
  321.     return ctr;
  322. }
  323.  
  324. void
  325. SendBreak()
  326. {
  327.     Assert(Iosr.IOSer.io_Device);
  328.     Ioss.IOSer.io_Command = SDCMD_BREAK;
  329.     DoIO(&Ioss);
  330. }
  331.  
  332. int
  333. CheckCarrier()
  334. {
  335.     Assert(Iosr.IOSer.io_Device);
  336.     Ioss.IOSer.io_Command = SDCMD_QUERY;
  337.     DoIO(&Ioss);
  338.     if (IgnoreCD)
  339.     return(1);
  340.     if (Ioss.io_Status & CIAF_COMCD)    /*  non-zero == no carrier */
  341.     return(0);
  342.     return(1);
  343. }
  344.  
  345. void *
  346. bzero(s, cnt)
  347. void   *s;
  348. long   cnt;
  349. {
  350.     setmem(s, cnt, 0);
  351.     return(s);
  352. }
  353.  
  354. void *
  355. bcopy(from, to, cnt)
  356. const void   *from;
  357. void   *to;
  358. long   cnt;
  359. {
  360.     movmem(from, to, cnt);
  361.     return(to);
  362. }
  363.  
  364. /*
  365.  * Transform a filename from a uucp packet (in Unix format) into a local
  366.  * filename that will work in the local file system.
  367.  */
  368.  
  369. void
  370. munge_filename(s, d)
  371. char *s, *d;
  372. {
  373.     if (*s != '~') {
  374.     if (s != d)
  375.         strcpy(d, s);
  376.     return;
  377.     }
  378.  
  379.     /*
  380.      *    ~/ ...    convert to UUPUB:
  381.      *    ~user/...   convert to <homedir>/...
  382.      */
  383.  
  384.     {
  385.     short i;
  386.     short c;
  387.     char *t;
  388.     struct passwd *pw;
  389.  
  390.     for (i = 1; s[i] && s[i] != '/'; ++i);
  391.     c = s[i];
  392.  
  393.     s[i] = 0;
  394.     if (i == 1)
  395.         pw = NULL;
  396.     else
  397.         pw = getpwnam(s + 1);
  398.     s[i] = c;
  399.  
  400.     if (c == '/')
  401.         ++i;
  402.  
  403.     if (pw) {
  404.         t = malloc(strlen(pw->pw_dir) + strlen(s + i) + 1);
  405.         strcpy(t, pw->pw_dir);
  406.     } else {
  407.         t = malloc(strlen(s + i) + 32);
  408.         strcpy(t, GetConfigDir(UUPUB));
  409.     }
  410.     strcat(t, s + i);
  411.     strcpy(d, t);
  412.     free(t);
  413.     }
  414. }
  415.  
  416. int
  417. hangup()
  418. {
  419.     static char buf[128];
  420.  
  421.     reset_modem();
  422.  
  423.     sprintf(buf, "run >nil: <nil: %s", GetConfigProgram(UUXQT));
  424.  
  425.     if (PriMode)
  426.     SetTaskPri(FindTask(NULL), OldPri - 1);
  427.  
  428.     if (Execute(buf, NULL, NULL) == 0)
  429.     puts("Unable to run UUXQT");
  430.  
  431.     if (PriMode)
  432.     SetTaskPri(FindTask(NULL), OldPri + 1);
  433.  
  434.     return SUCCESS;
  435. }
  436.  
  437. static char names[MAXFILES*16];
  438. static char *pointers[MAXFILES];
  439. static int file_pointer;
  440.  
  441. int
  442. bp_strcmp(s1, s2)
  443. char **s1;
  444. char **s2;
  445. {
  446.     return(strcmp(*s1, *s2));
  447. }
  448.  
  449. int
  450. work_scan(system_name)
  451. char *system_name;
  452. {
  453.     static char name[128];
  454.     int count;
  455.  
  456.     file_pointer = 0;
  457.  
  458.     if (strlen(system_name) > 7)
  459.     system_name[7] = '\0';
  460.  
  461.     sprintf(name, "%sC.%s#?", MakeConfigPath(UUSPOOL, ""), system_name);
  462.  
  463.     if (debug > 2)
  464.     printf("Looking for %s\n",name);
  465.  
  466.     count = getfnl(name,names,sizeof(names),0);
  467.  
  468.     if (count > 0) {
  469.     if (strbpl(pointers,MAXFILES,names) != count) {
  470.         printf("Too many command files for %s.\n",system_name);
  471.         return(0);
  472.     }
  473.     } else {
  474.     return(0);
  475.     }
  476.     qsort(pointers, count, sizeof(char *), bp_strcmp);
  477.     if (debug > 2)
  478.     printf("Found -> %s\n", pointers[file_pointer]);
  479.     return(1);
  480. }
  481.  
  482. char *
  483. work_next()
  484. {
  485.     char *ptr;
  486.  
  487.     if (ptr = pointers[file_pointer]) {
  488.     if (debug > 2)
  489.         printf("Found -> %s\n", ptr);
  490.     ++file_pointer;
  491.     }
  492.     return(ptr);
  493. }
  494.  
  495. void
  496. amiga_setup()
  497. {
  498.     mountrequest(0);        /*  disallow requesters */
  499.  
  500.     OpenSerial(1);
  501.  
  502.     if (OpenDevice(TIMERNAME, UNIT_VBLANK, &Iot0, 0))  {
  503.     Iot0.tr_node.io_Device = NULL;
  504.     printf("Can't open timer device.");
  505.     xexit(4);
  506.     }
  507.  
  508.     Iot0.tr_node.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("UUCICO-Timer", 0L);
  509.     Iot0.tr_node.io_Command = TR_ADDREQUEST;
  510.     Iot0.tr_node.io_Error = 0;
  511.  
  512.     {
  513.     struct Task *task = (struct Task *)FindTask(NULL);
  514.     OldTaskName = task->tc_Node.ln_Name;
  515.     task->tc_Node.ln_Name = "uucico";
  516.     }
  517. }
  518.  
  519. void
  520. set_baud(baud)
  521. int baud;
  522. {
  523.     Assert(Iosr.IOSer.io_Device);
  524.  
  525.     /*
  526.      *    only modify serial parameters if not run from a Getty.    This is
  527.      *    to get around a bug in the A2232 serial.device (possibly also
  528.      *    the normal serial.device) having to do with hanging semaphores.
  529.      *
  530.      *    it is also possible that this might be desirable for operation.
  531.      */
  532.  
  533.     if (Getty == 0) {
  534.     Iosr.IOSer.io_Command = SDCMD_SETPARAMS;
  535.     Iosr.io_SerFlags =  SERF_SHARED | SERF_XDISABLED;
  536.     Iosr.io_Baud = baud;
  537.     Iosr.io_ReadLen = 8L;
  538.     Iosr.io_WriteLen = 8L;
  539.     Iosr.io_CtlChar = 0x11130000L;
  540.     Iosr.io_RBufLen = 4096;
  541.  
  542.     if (SevenWire)
  543.         Iosr.io_SerFlags |= SERF_7WIRE;
  544.  
  545.     DoIO(&Iosr);
  546.     }
  547. }
  548.  
  549. void
  550. OpenSerial(lock)
  551. int lock;
  552. {
  553.     if (Iosr.IOSer.io_Device) {
  554.     puts("softerror, OpenSerial: Serial Port already open!");
  555.     return;
  556.     }
  557.  
  558.     Iosr.io_SerFlags = SERF_SHARED | SERF_XDISABLED;
  559.     Iosr.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Read_RS",0);
  560.  
  561.     if (SevenWire)
  562.     Iosr.io_SerFlags |= SERF_7WIRE;
  563.  
  564.     if (lock && Getty == 0)
  565.     LockSerialPort(DeviceName, DeviceUnit);
  566.  
  567.     if (OpenDevice(DeviceName, DeviceUnit, &Iosr, NULL)) {
  568.     Iosr.IOSer.io_Device = NULL;
  569.     DeletePort(Iosr.IOSer.io_Message.mn_ReplyPort);
  570.     Iosr.IOSer.io_Message.mn_ReplyPort = NULL;
  571.     printf("Can not open serial port for read.\n");
  572.     xexit(TRUE);
  573.     }
  574.  
  575.     Iosw = Iosr;
  576.     Iosw.IOSer.io_Message.mn_ReplyPort = (struct MsgPort *)CreatePort("Write_RS", 0);
  577.     Ioss = Iosw;
  578.  
  579.     Iosr.IOSer.io_Command = SDCMD_QUERY;
  580.     DoIO(&Iosr);
  581.  
  582.     set_baud(Iosr.io_Baud);
  583. }
  584.  
  585. void
  586. CloseSerial(lock)
  587. int lock;
  588. {
  589.     if (IosrIP) {
  590.     AbortIO(&Iosr);
  591.     WaitIO(&Iosr);
  592.     IosrIP = 0;
  593.     }
  594.     if (IotIP) {
  595.     AbortIO(&Iot0);
  596.     WaitIO(&Iot0);
  597.     IotIP = 0;
  598.     }
  599.     if (IoswIP) {
  600.     WaitIO(&Iosw);
  601.     IoswIP = 0;
  602.     }
  603.     if (Iosr.IOSer.io_Device) {
  604.     CloseDevice(&Iosr);
  605.     Iosr.IOSer.io_Device = NULL;
  606.     Iosw.IOSer.io_Device = NULL;
  607.     Ioss.IOSer.io_Device = NULL;
  608.     } else {
  609.     puts("softerr, CloseSerial: Serial Port already closed!");
  610.     }
  611.     if (Iosr.IOSer.io_Message.mn_ReplyPort) {
  612.     DeletePort(Iosr.IOSer.io_Message.mn_ReplyPort);
  613.     Iosr.IOSer.io_Message.mn_ReplyPort = NULL;
  614.     }
  615.     if (Iosw.IOSer.io_Message.mn_ReplyPort) {
  616.     DeletePort(Iosw.IOSer.io_Message.mn_ReplyPort);
  617.     Iosw.IOSer.io_Message.mn_ReplyPort = NULL;
  618.     }
  619.     if (lock && Getty == 0)
  620.     UnLockSerialPort(DeviceName, DeviceUnit);
  621. }
  622.  
  623. void
  624. xexit(code)
  625. int code;
  626. {
  627.     signal(SIGINT, SIG_IGN);
  628.  
  629.     ++InExitRoutine;
  630.  
  631.     if (InExitRoutine == 1 && code && Iosr.IOSer.io_Device && CheckCarrier())
  632.     reset_modem();
  633.  
  634.     CloseSerial(1);
  635.  
  636.     {
  637.     struct Task *task = (struct Task *)FindTask(NULL);
  638.     if (OldTaskName)
  639.         task->tc_Node.ln_Name = OldTaskName;
  640.     }
  641.  
  642.     if (Iot0.tr_node.io_Device) {
  643.     CloseDevice(&Iot0);
  644.     Iot0.tr_node.io_Device = NULL;
  645.     }
  646.     if (Iot0.tr_node.io_Message.mn_ReplyPort) {
  647.     DeletePort(Iot0.tr_node.io_Message.mn_ReplyPort);
  648.     Iot0.tr_node.io_Message.mn_ReplyPort = NULL;
  649.     }
  650.     chdir(path);
  651.     if (code)
  652.     printf("\nAbnormal Termination, code %d.\n", code);
  653.  
  654.     mountrequest(1);
  655.  
  656.     UnLockFiles();      /*  unlock any hanging locks */
  657.  
  658.     exit(code);
  659. }
  660.  
  661. void
  662. printc(c)
  663. unsigned char c;
  664. {
  665.     c &= 0x7F;
  666.  
  667.     if (c < 32)
  668.     printf("^%c", c | 0x40);
  669.     else if (c == 32)
  670.     printf("_");
  671.     else if (c < 128)
  672.     printf("%c", c);
  673.     else
  674.     printf("(%02x)", c);
  675. }
  676.  
  677. void
  678. _assert_failed(line)
  679. {
  680.     static short reent;
  681.  
  682.     if (reent == 0) {
  683.     ++reent;
  684.     printf("Software Error line %d sysdep.c (uucico)\n", line);
  685.     xexit(5);
  686.     }
  687. }
  688.  
  689.